# 自己写的asgi服务
import urllib.parse
import json

CONNECTIONS = {}


# 判断用户是否已经连接, 在线就可以直接发送过去了
def check_connection(key):
    return key in CONNECTIONS


# 发送消息结构体
def message(sender, msg_type, msg):
    """

    :param sender: string 发送过来的是谁 system就算系统发送的
    :param msg_type: string 发送的类型
    :param msg: string 发送的内容
    :return:
        一个字典
    """
    text = json.dumps({
        'sender': sender,
        'contentType': msg_type,
        'content': msg,
    })
    return {
        'type': 'websocket.send',
        'text': text
    }


print(CONNECTIONS)


async def websocket_application(scope, receive, send):
    while True:
        event = await receive()
        print('event: %s' % event)  # {'type': 'websocket_chat.connect'} 队列
        query_string = scope.get('query_string', b'').decode()
        qs = urllib.parse.parse_qs(query_string)
        user_id = qs.get('user_id', [''])[0]
        # 收到建立websocket连接的消息
        if event['type'] == 'websocket.connect':
            print('建立链接了')
            # 用户id验证
            if not user_id:
                break
            if user_id in CONNECTIONS:
                # 如果用户已经登陆了
                break

            await send({'type': 'websocket.accept'})
            # TODO 这只是简单的吧全部人返回去，应该去数据库查出那些是他的好友
            friends_id_list = list(CONNECTIONS.keys())

            await send(message('system', 'friendsList', friends_id_list))

            # 向其他人群发消息, 有人登录了，告诉别人我上线了
            for other in CONNECTIONS.values():
                # other 就是其他人的发送器
                await other(message('system', 'addFriend', user_id))

            # 记录send对象
            CONNECTIONS[user_id] = send

        # 收到中断websocket连接的消息
        elif event['type'] == 'websocket.disconnect':  # 如果跳出链接
            # 移除记录
            if user_id in CONNECTIONS:
                CONNECTIONS.pop(user_id)

            # 向其他人群发消息, 有人离线了
            for other in CONNECTIONS.values():
                await other(message('system', 'removeFriend', user_id))


        # 正常websock消息了 event: {'type': 'websocket_chat.receive', 'text': '你好'}
        elif event['type'] == 'websocket.receive':
            print('正常收到消息了')

            if event['text'] == 'ping':
                await send({
                    'type': 'websocket.send',
                    'text': 'pong'
                })
            else:
                receive_msg = json.loads(event['text'])
                send_to = receive_msg.get('sendTo', '')
                # 如果要发送的人在线
                if send_to in CONNECTIONS:
                    content_type = receive_msg.get('contentType', 'text')
                    content = receive_msg.get('content', '')
                    msg = message(user_id, content_type, content)
                    await CONNECTIONS[send_to](msg)
                else:
                    msg = message('system', 'text', '对方已下线或不存在')
                    await send(msg)  # 返回去告诉发送者，好友已经下线了

        else:
            pass

    print('[disconnect]')
    pass
